package search;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Pattern;

import act.ActorFactory;
import act.End;
import act.IActor;

public class SrchMain {

	private static class ExecThreadPerTask implements Executor
	{	
	
		@Override
		public void execute(Runnable command) {
			Thread t = new Thread(command, "athread");
			t.start();				
		}

	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
	
		if(args.length != 1)
		{
			System.out.println("Enter a directory to search");
			return;
		}
		
		String dir = args[0];

		testEchoOne();
		//testEchoDir(dir);
		//testStraight(dir);
		testSplit(dir);
		
	}

	private static final int MAILBOX_SIZE = 100;

	
	public static void testSplit(String dir) {
		
		long start = System.currentTimeMillis();
		
		ActorFactory factory = new ActorFactory(new ExecThreadPerTask());
		Pattern pattern = Pattern.compile(".*test.*");
		
		//set it up so that we have
		// dir -> Distributor -> 5x grep -> EndJoin -> echo

		int numGreppers = 5;		

		IActor echo = factory.create(new Echo(), MAILBOX_SIZE);
		IActor EndJoin = factory.create(new EndJoin(numGreppers, echo));

		IActor[] greppers = new IActor[numGreppers];
		for(int i = 0; i < numGreppers; i++)
		{
			greppers[i] = factory.create(new Grep(pattern, EndJoin), MAILBOX_SIZE);
		}
		
		IActor distrib = factory.create(new Distributor(greppers));
		
		//send the output of dir method to distrib which will 
		//send on to greps which will send on to EndJoin which will send on to Echo
		Dir.dir(dir, ".*java", true, distrib);
					
		echo.await();

		System.out.println("time for testSplit = " + (System.currentTimeMillis() - start));

	}

	
	public static void testEchoOne()
	{
		ExecutorService service = Executors.newCachedThreadPool();
		ActorFactory factory = new ActorFactory(service);
		IActor echo = factory.create(new Echo(), MAILBOX_SIZE);
		echo.send("test");
		echo.send(new End());
		
		echo.await();
		
		//this will cause the service to auto-stop all threads when all tasks that have been added so far are finished
		//i.e. when all actors are finished processing their queues
		service.shutdown();
	}
	
	public static void testEchoDir(String dir)
	{
		ExecutorService service = Executors.newCachedThreadPool();
		ActorFactory factory = new ActorFactory(service);

		IActor echo = factory.create(new Echo(), MAILBOX_SIZE);

		
		Dir.dir(dir, ".*java", true, echo);
		
		echo.await();

		//this will caust the service to auto-stop all threads when all tasks that have been added so far are finished
		//i.e. when all actors are finished processing their queues
		service.shutdown();
	}
	
	public static void testStraight(String dir) {
		
		//ExecutorService service = Executors.newCachedThreadPool();
		
		long start = System.currentTimeMillis();
		
		ActorFactory factory = new ActorFactory(new ExecThreadPerTask());

		//set it up so that we have
		// dir -> grep -> echo
		
		IActor echo = factory.create(new Echo(), MAILBOX_SIZE);
		
		Pattern pattern = Pattern.compile(".*test.*");
		//send the output of grep to echo
		IActor grep = factory.create(new Grep(pattern, echo), MAILBOX_SIZE);
		
		//send the output of dir method to grep
		Dir.dir(dir, ".*java", true, grep);

	
		echo.await();
		
		System.out.println("time for testStraight = " + (System.currentTimeMillis() - start));
		//this will cause the service to auto-stop all threads when all tasks that have been added so far are finished
		//i.e. when all actors are finished processing their queues
		//service.shutdown();
		

	}

	

}

